package com.mew.chess.core.game.bjl.game;

import cn.hutool.core.date.DateUtil;
import com.mew.chess.core.game.bjl.game.common.BjlConstantValue;
import com.mew.chess.core.game.bjl.game.common.BjlLinkType;
import com.mew.chess.core.game.bjl.game.task.*;
import com.mew.common.config.SpringContextBean;
import com.zebra.common.concurrent.ZebraScheduler;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


/**
 * @author dylin
 */
@Data
@ToString(of = {"roomId"})
@NoArgsConstructor
@Slf4j
public class BjlScheduleManager {
    private AtomicBoolean flag = new AtomicBoolean(false);

    private int roomId;

    private ZebraScheduler zebraScheduler;
    private ExecutorService executorService;

    private ScheduledFuture<?> scheduledFuture;
    private ScheduledFuture<?> scheduledFutureCycle;

    private BjlShuffleCardTask shuffleCardTask;
    private BjlDealCardTask dealCardTask;
    private BjlOpenCardTask openCardTask;
    private BjlStartBetTask startBetTask;
    private BjlPaymentTask paymentTask;
    private BjlPushBetScheduleTask pushBetScheduleTask;

    public BjlScheduleManager(int roomId, ZebraScheduler zebraScheduler, ExecutorService executorService){
        this.roomId = roomId;
        this.zebraScheduler = zebraScheduler;
        this.executorService = executorService;
    }

    private void initializeTask(){

        if (null == shuffleCardTask){
            shuffleCardTask = SpringContextBean.getBean(BjlShuffleCardTask.class);
        }
        if (null == dealCardTask){
            dealCardTask = SpringContextBean.getBean(BjlDealCardTask.class);
        }
        if (null == startBetTask){
            startBetTask = SpringContextBean.getBean(BjlStartBetTask.class);
        }
        if (null == pushBetScheduleTask){
            pushBetScheduleTask = new BjlPushBetScheduleTask();
        }

        if (null == openCardTask){
            openCardTask = SpringContextBean.getBean(BjlOpenCardTask.class);
        }

        if (null == paymentTask){
            paymentTask = SpringContextBean.getBean(BjlPaymentTask.class);
        }


    }

    public void start(){
        if(flag.compareAndSet(false, true)){
            initializeTask();
            prepareStartTimer();
        }
    }

    public void stop(){
        ZebraScheduler.cancelScheduled(scheduledFuture);
        flag.getAndSet(false);
    }

    /**
     * 准备阶段
     */
    private void prepareStartTimer(){
        BjlRoomManager roomManager =  BjlGameManager.getInstance().getController(roomId);
        roomManager.changeLink(BjlLinkType.Prepare.code(),BjlConstantValue.PREPARE_TIME);
        scheduledFuture = zebraScheduler.schedule((this::doShuffleCard), BjlConstantValue.PREPARE_TIME, TimeUnit.MILLISECONDS, executorService);
    }
    /**
     * 洗牌
     */
    private void doShuffleCard(){
        BjlRoomManager roomManager =  BjlGameManager.getInstance().getController(roomId);
        if(roomManager.getCardLib().size()<7){
            if (!shuffleCardTask.shuffle(roomId)){
                return;
            }
            scheduledFuture = zebraScheduler.schedule((this::doDealCard), BjlConstantValue.SHUFFLE_TIME, TimeUnit.MILLISECONDS, executorService);
        }else{
            doDealCard();
        }

    }
    /**
     * 发牌阶段
     */
    private void doDealCard(){
        if (!dealCardTask.dealCard(roomId)){
            return;
        }
        scheduledFuture = zebraScheduler.schedule((this::doStartBet), BjlConstantValue.DEAL_CARD_TIME, TimeUnit.MILLISECONDS, executorService);
    }
    /**
     *压注阶段
     */
    private void doStartBet(){
        startBetTask.startBet(roomId);
        scheduledFutureCycle = zebraScheduler.scheduleWithFixedDelay((this::doCycleRobotBet), 600L, BjlConstantValue.PLAY_PUSH, TimeUnit.MILLISECONDS, executorService);
        scheduledFuture = zebraScheduler.schedule((this::doOpenCard), BjlConstantValue.START_BET_TIME, TimeUnit.MILLISECONDS, executorService);
    }

    /**
     * 机器人压注推送
     */
    private void doCycleRobotBet(){
        pushBetScheduleTask.robotBet(roomId, scheduledFutureCycle);
    }

    /**
     * 开牌阶段
     */
    private void doOpenCard(){
        ZebraScheduler.cancelScheduled(scheduledFutureCycle);
        openCardTask.openCard(roomId);
        scheduledFuture = zebraScheduler.schedule((this::doPayment), BjlConstantValue.OPEN_CARD_TIME, TimeUnit.MILLISECONDS, executorService);
    }
    /**
     * 开牌阶段
     */
    private void doPayment(){
        ZebraScheduler.cancelScheduled(scheduledFutureCycle);
        paymentTask.payment(roomId);
        scheduledFuture = zebraScheduler.schedule((this::doShuffleCard), BjlConstantValue.PAYMENT_TIME, TimeUnit.MILLISECONDS, executorService);
    }
}
